#import "RNHoverLinkButtonCell.h"

@interface RNHoverLinkButtonCell ()
@property (nonatomic, assign) BOOL hovering;
@end

@interface RNHoverLinkButtonCell (RNHoverLinkButtonCellPrivateMethods)
-(void)initializeState_;
@end

@implementation RNHoverLinkButtonCell

@synthesize normalAttributes = normalAttributes_;
@synthesize hoverAttributes = hoverAttributes_;
@synthesize textColor = textColor_;
@synthesize textHoverColor = textHoverColor_;
@synthesize hovering = hovering_;

+ (BOOL)prefersTrackingUntilMouseUp {
    return YES;
}

-(id)initTextCell:(NSString *)aString {
    if (!(self = [super initTextCell:aString]))
        return nil;
    [self initializeState_];
    return self;
}

-(id)initWithCoder:(NSCoder *)coder {
    if (!(self = [super initWithCoder:coder]))
        return nil;
    [self initializeState_];
    return self;
}

-(id)copyWithZone:(NSZone *)zone {
    RNHoverLinkButtonCell *cell = [super copyWithZone:zone];
    [cell initializeState_];
    return cell;
}

-(void)initializeState_ {
    [self setHighlightsBy:NSNoCellMask];
    [self setBordered:NO];
    [self setTextColor:[NSColor blackColor]];
    [self setTextHoverColor:[NSColor blackColor]];
}

-(NSRect)titleRectForBounds:(NSRect)theRect {
    NSRect titleRect = [super titleRectForBounds:theRect];
    CGFloat titleWidth = [[self attributedTitle] size].width;
    titleRect.size.width = titleWidth;
    return titleRect;
}

-(void)addTrackingAreasForView:(NSView *)view inRect:(NSRect)cellFrame withUserInfo:(NSDictionary *)userInfo mouseLocation:(NSPoint)currentPoint {
    NSRect titleRect = [self titleRectForBounds:cellFrame];
    CGFloat titleWidth = [[self attributedTitle] size].width;
    titleRect.size.width = titleWidth;
    NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:titleRect options:NSTrackingMouseEnteredAndExited | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveInActiveApp owner:view userInfo:userInfo];
    [view addTrackingArea:trackingArea];
    [self setHovering:[view mouse:currentPoint inRect:[self titleRectForBounds:cellFrame]]];
    [(NSControl *)[self controlView] updateCell:self];
}

-(BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)untilMouseUp {
    NSRect titleRect = [self titleRectForBounds:cellFrame];
    while ([theEvent type] != NSLeftMouseUp) {
        if ([theEvent type] == NSMouseEntered || [theEvent type] == NSMouseExited) 
            [NSApp sendEvent:theEvent];
        theEvent = [[controlView window] nextEventMatchingMask:(NSLeftMouseUpMask | NSLeftMouseDraggedMask | NSMouseEnteredMask | NSMouseExitedMask)];
    }

    NSPoint eventPoint = [controlView convertPoint:[theEvent locationInWindow] fromView:nil];
    if ([controlView mouse:eventPoint inRect:titleRect])
        [NSApp sendAction:[self action] to:[self target] from:self];
    return YES;
}

-(void)mouseEntered:(NSEvent *)event {
    [self setHovering:YES];
    [(NSControl *)[self controlView] updateCell:self];
}

-(void)mouseExited:(NSEvent *)event {
    [self setHovering:NO];
    [(NSControl *)[self controlView] updateCell:self];
}

-(NSAttributedString *)attributedTitle {
    NSDictionary *currentAttributes = [self hovering] ? [self hoverAttributes] : [self normalAttributes];
    return [[NSAttributedString alloc] initWithString:[self title] attributes:currentAttributes];
}

-(NSDictionary *)normalAttributes {
    if (!normalAttributes_) {
        NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
        [attributes setValue:[NSFont controlContentFontOfSize:11.0f] forKey:NSFontAttributeName];
        [attributes setValue:[self textColor] forKey:NSForegroundColorAttributeName];
        normalAttributes_ = (NSDictionary *)attributes;
    }
    return normalAttributes_;
}

-(NSDictionary *)hoverAttributes {
    if (!hoverAttributes_) {
        NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
        [attributes setValue:[NSFont controlContentFontOfSize:11.0f] forKey:NSFontAttributeName];
        [attributes setValue:[NSNumber numberWithInteger:NSUnderlineStyleSingle | NSUnderlinePatternSolid] forKey:NSUnderlineStyleAttributeName];
        [attributes setValue:[self textHoverColor] forKey:NSForegroundColorAttributeName];
        hoverAttributes_ = (NSDictionary *)attributes;
    }
    return hoverAttributes_;
}

@end
